<?php

namespace App\Http\Controllers;

use App\Http\Requests\TransferController\TransferInRequest;
use App\Http\Requests\TransferController\TransferRequest;
use App\Http\Resources\TransferResource;
use App\Models\Account;
use App\Models\Transfer;
use App\Models\TransferIn;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Throwable;
use Xrfg\Core\Trading\Account\Models\Account as TradingAccount;

/**
 * 转移.
 * Class TransferController
 * @package App\Http\Controllers
 */
class TransferController extends Controller
{
    /**
     * DSE质押币转移记录（A用户->B用户）
     */
    public function index(Request $request)
    {
        $perPage = $request->query('per_page', 15);
        $perPage = $perPage > 100 ? 100 : $perPage;
        $coin_id = $request->query('coin_id');

        $list = Transfer::when($coin_id, function ($query) use ($coin_id) {
            $query->where('coin_id', $coin_id);
        })
            ->where(function ($query) {
                return $query->where('from_user_id', Auth::id())
                    ->orWhere('to_user_id', Auth::id());
            })
            ->orderByDesc('id')
            ->paginate($perPage);

        return TransferResource::collection($list);
    }

    /**
     * DSE质押币转移（A用户->B用户）
     */
    public function transfer(TransferRequest $request)
    {
        $to_username = $request->input('to_username');
        $transfer_number = $request->input('transfer_number');
        $fee = bcmul($transfer_number, 0);

        /** @var User $user */
        $user = Auth::user();
        // 市值账户(dse888888@163.com)禁止转移
        if ($user->id == 1180) {
            $this->error(20007);
        }
        /** @var User $toUser */
        $toUser = User::where('username', $to_username)->first();
        if ($user->id == $toUser->id) { // 不能向自己转账
            $this->error(30009);
        }

        // 只能转移到有层级关系的账户，且只能由上级转到下级
//         if (!User::where('_lft', '>', $user->_lft)->where('_rgt', '<', $user->_rgt)->where('id', $toUser->id)->exists()) {
//             $this->error(30010);
//         }

        // 余额检测
        /** @var Account $outAccount */
        $outAccount = Account::firstOrCreate([
            'user_id' => $user->id,
            'coin_id' => 2,
        ])->refresh();
        if ($outAccount->available < bcadd($transfer_number, $fee)) {
            $this->error(20002);
        }

        /** @var Account $inAccount */
        $inAccount = Account::firstOrCreate([
            'user_id' => $toUser->id,
            'coin_id' => 2,
        ]);

        // 转账记录
        $transfer = new Transfer();
        $transfer->from_user_id = $user->id;
        $transfer->to_user_id = $toUser->id;
        $transfer->number = $transfer_number;
        $transfer->fee = $fee;
        $transfer->time = now();

        Log::info("转移，from_user：{$user->username}，to_user：{$toUser->username}，数量：{$transfer_number}");
        try {
            DB::transaction(function () use ($transfer, $outAccount, $inAccount) {
                /** @var Account $outAccount */
                $outAccount = Account::lockForUpdate()->find($outAccount->id);
                /** @var Account $inAccount */
                $inAccount = Account::lockForUpdate()->find($inAccount->id);

                $transfer->save();

                $outAccount->availableDecrement(bcadd($transfer->number, $transfer->fee));
                $outAccount->type = '转移';
                $outAccount->action_id = $transfer->id;
                $outAccount->save();

                $inAccount->availableIncrement($transfer->number);
                $inAccount->type = '转移';
                $inAccount->action_id = $transfer->id;
                $inAccount->save();
            });
        } catch (Throwable $exception) {
            Log::error($exception);
            $this->error();
        }

        Log::info("转移成功");
        return $this->null();
    }

    /**
     * DSE质押币划转（交易账户->质押币账户）.
     *
     * @param TransferInRequest $request
     *
     * @return \Illuminate\Http\Response
     */
    public function transferIn(TransferInRequest $request)
    {
        /** @var User $user */
        $user = Auth::user();
        $transfer_number = $request->input('transfer_number');
        $fee = bcmul($transfer_number, 0);

        // 出账账户
        $fromAccount = TradingAccount::firstOrCreate([
            'user_id' => $user->id,
            'coin_id' => 2,
        ]);
        if ($fromAccount->available < bcadd($transfer_number, $fee)) {
            $this->error(20002);
        }

        // 入账账户
        $toAccount = Account::firstOrCreate([
            'user_id' => $user->id,
            'coin_id' => 2,
        ])->refresh();

        // 资金划转记录
        $transfer = new TransferIn();
        $transfer->user_id = $user->id;
        $transfer->number = $transfer_number;
        $transfer->fee = $fee;

        // 保存数据
        bcscale(8);
        try {
            DB::transaction(function () use ($fromAccount, $toAccount, $transfer) {
                /** @var TradingAccount $fromAccount */
                $fromAccount = TradingAccount::lockForUpdate()->find($fromAccount->id);
                /** @var Account $toAccount */
                $toAccount = Account::lockForUpdate()->find($toAccount->id);

                $transfer->save();

                $fromAccount->availableDecrement(bcadd($transfer->number, $transfer->fee));
                $fromAccount->proofId = [$transfer->id, 3, 2];
                $fromAccount->save();

                $toAccount->availableIncrement($transfer->number);
                $toAccount->type = '质押币转入';
                $toAccount->action_id = $transfer->id;
                $toAccount->save();
            });
        } catch (Throwable $exception) {
            Log::error($exception);
            $this->error();
        }

        return $this->null();
    }
}
